home *** CD-ROM | disk | FTP | other *** search
/ Info-Mac 11 / Info-Mac_XI_Disc_1.cdr_ / Info-Mac XI Disc 1.cdr / Programs / Science & Math / MacEspresso 1.0 / espresso / hack.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-12-10  |  17.3 KB  |  631 lines  |  [TEXT/R*ch]

  1. #include "espresso.h"
  2.  
  3. map_dcset(PLA)
  4. pPLA PLA;
  5. {
  6.     int var, i;
  7.     pcover Tplus, Tminus, Tplusbar, Tminusbar;
  8.     pcover newf, term1, term2, dcset, dcsetbar;
  9.     pcube cplus, cminus, last, p;
  10.  
  11.     if (PLA->label == NIL(char *) || PLA->label[0] == NIL(char))
  12.     return;
  13.  
  14.     /* try to find a binary variable named "DONT_CARE" */
  15.     var = -1;
  16.     for(i = 0; i < cube.num_binary_vars * 2; i++) {
  17.     if (strncmp(PLA->label[i], "DONT_CARE", 9) == 0 ||
  18.       strncmp(PLA->label[i], "DONTCARE", 8) == 0 ||
  19.       strncmp(PLA->label[i], "dont_care", 9) == 0 ||
  20.       strncmp(PLA->label[i], "dontcare", 8) == 0) {
  21.         var = i/2;
  22.         break;
  23.     }
  24.     }
  25.     if (var == -1) {
  26.     return;
  27.     }
  28.  
  29.     /* form the cofactor cubes for the don't-care variable */
  30.     cplus = set_save(cube.fullset);
  31.     cminus = set_save(cube.fullset);
  32.     set_remove(cplus, var*2);
  33.     set_remove(cminus, var*2 + 1);
  34.  
  35.     /* form the don't-care set */
  36.     EXEC(simp_comp(cofactor(cube1list(PLA->F), cplus), &Tplus, &Tplusbar),
  37.     "simpcomp+", Tplus);
  38.     EXEC(simp_comp(cofactor(cube1list(PLA->F), cminus), &Tminus, &Tminusbar),
  39.     "simpcomp-", Tminus);
  40.     EXEC(term1 = cv_intersect(Tplus, Tminusbar), "term1    ", term1);
  41.     EXEC(term2 = cv_intersect(Tminus, Tplusbar), "term2    ", term2);
  42.     EXEC(dcset = sf_union(term1, term2), "union     ", dcset);
  43.     EXEC(simp_comp(cube1list(dcset), &PLA->D, &dcsetbar), "simplify", PLA->D);
  44.     EXEC(newf = cv_intersect(PLA->F, dcsetbar), "separate  ", PLA->F);
  45.     free_cover(PLA->F);
  46.     PLA->F = newf;
  47.     free_cover(Tplus);
  48.     free_cover(Tminus);
  49.     free_cover(Tplusbar);
  50.     free_cover(Tminusbar);
  51.     free_cover(dcsetbar);
  52.  
  53.     /* remove any cubes dependent on the DONT_CARE variable */
  54.     (void) sf_active(PLA->F);
  55.     foreach_set(PLA->F, last, p) {
  56.     if (! is_in_set(p, var*2) || ! is_in_set(p, var*2+1)) {
  57.         RESET(p, ACTIVE);
  58.     }
  59.     }
  60.     PLA->F = sf_inactive(PLA->F);
  61.  
  62.     /* resize the cube and delete the don't-care variable */
  63.     setdown_cube();
  64.     for(i = 2*var+2; i < cube.size; i++) {
  65.     PLA->label[i-2] = PLA->label[i];
  66.     }
  67.     for(i = var+1; i < cube.num_vars; i++) {
  68.     cube.part_size[i-1] = cube.part_size[i];
  69.     }
  70.     cube.num_binary_vars--;
  71.     cube.num_vars--;
  72.     cube_setup();
  73.     PLA->F = sf_delc(PLA->F, 2*var, 2*var+1);
  74.     PLA->D = sf_delc(PLA->D, 2*var, 2*var+1);
  75. }
  76.  
  77. map_output_symbolic(PLA)
  78. pPLA PLA;
  79. {
  80.     pset_family newF, newD;
  81.     pset compress;
  82.     symbolic_t *p1;
  83.     symbolic_list_t *p2;
  84.     int i, bit, tot_size, base, old_size;
  85.  
  86.     /* Remove the DC-set from the ON-set (is this necessary ??) */
  87.     if (PLA->D->count > 0) {
  88.     sf_free(PLA->F);
  89.     PLA->F = complement(cube2list(PLA->D, PLA->R));
  90.     }
  91.  
  92.     /* tot_size = width added for all symbolic variables */
  93.     tot_size = 0;
  94.     for(p1=PLA->symbolic_output; p1!=NIL(symbolic_t); p1=p1->next) {
  95.     for(p2=p1->symbolic_list; p2!=NIL(symbolic_list_t); p2=p2->next) {
  96.         if (p2->pos<0 || p2->pos>=cube.part_size[cube.output]) {
  97.         fatal("symbolic-output index out of range");
  98. /*        } else if (p2->variable != cube.output) {
  99.         fatal("symbolic-output label must be an output");*/
  100.         }
  101.     }
  102.     tot_size += 1 << p1->symbolic_list_length;
  103.     }
  104.  
  105.     /* adjust the indices to skip over new outputs */
  106.     for(p1=PLA->symbolic_output; p1!=NIL(symbolic_t); p1=p1->next) {
  107.     for(p2=p1->symbolic_list; p2!=NIL(symbolic_list_t); p2=p2->next) {
  108.         p2->pos += tot_size;
  109.     }
  110.     }
  111.  
  112.     /* resize the cube structure -- add enough for the one-hot outputs */
  113.     old_size = cube.size;
  114.     cube.part_size[cube.output] += tot_size;
  115.     setdown_cube();
  116.     cube_setup();
  117.  
  118.     /* insert space in the output part for the one-hot output */
  119.     base = cube.first_part[cube.output];
  120.     PLA->F = sf_addcol(PLA->F, base, tot_size);
  121.     PLA->D = sf_addcol(PLA->D, base, tot_size);
  122.     PLA->R = sf_addcol(PLA->R, base, tot_size);
  123.  
  124.     /* do the real work */
  125.     for(p1=PLA->symbolic_output; p1!=NIL(symbolic_t); p1=p1->next) {
  126.     newF = new_cover(100);
  127.     newD = new_cover(100);
  128.     find_inputs(NIL(set_family_t), PLA, p1->symbolic_list, base, 0,
  129.                 &newF, &newD);
  130. /*
  131.  *  Not sure what this means
  132.     find_dc_inputs(PLA, p1->symbolic_list,
  133.                 base, 1 << p1->symbolic_list_length, &newF, &newD);
  134.  */
  135.     free_cover(PLA->F);
  136.     PLA->F = newF;
  137. /*
  138.  *  retain OLD DC-set -- but we've lost the don't-care arc information
  139.  *  (it defaults to branch to the zero state)
  140.     free_cover(PLA->D);
  141.     PLA->D = newD;
  142.  */
  143.     free_cover(newD);
  144.     base += 1 << p1->symbolic_list_length;
  145.     }
  146.  
  147.     /* delete the old outputs, and resize the cube */
  148.     compress = set_full(newF->sf_size);
  149.     for(p1=PLA->symbolic_output; p1!=NIL(symbolic_t); p1=p1->next) {
  150.     for(p2=p1->symbolic_list; p2!=NIL(symbolic_list_t); p2=p2->next) {
  151.         bit = cube.first_part[cube.output] + p2->pos;
  152.         set_remove(compress, bit);
  153.     }
  154.     }
  155.     cube.part_size[cube.output] -= newF->sf_size - set_ord(compress);
  156.     setdown_cube();
  157.     cube_setup();
  158.     PLA->F = sf_compress(PLA->F, compress);
  159.     PLA->D = sf_compress(PLA->D, compress);
  160.     if (cube.size != PLA->F->sf_size) fatal("error");
  161.  
  162.     /* Quick minimization */
  163.     PLA->F = sf_contain(PLA->F);
  164.     PLA->D = sf_contain(PLA->D);
  165.     for(i = 0; i < cube.num_vars; i++) {
  166.     PLA->F = d1merge(PLA->F, i);
  167.     PLA->D = d1merge(PLA->D, i);
  168.     }
  169.     PLA->F = sf_contain(PLA->F);
  170.     PLA->D = sf_contain(PLA->D);
  171.  
  172.     free_cover(PLA->R);
  173.     PLA->R = new_cover(0);
  174.  
  175.     symbolic_hack_labels(PLA, PLA->symbolic_output,
  176.                 compress, cube.size, old_size, tot_size);
  177.     set_free(compress);
  178. }
  179.  
  180.  
  181. find_inputs(A, PLA, list, base, value, newF, newD)
  182. pcover A;
  183. pPLA PLA;
  184. symbolic_list_t *list;
  185. int base, value;
  186. pcover *newF, *newD;
  187. {
  188.     pcover S, S1;
  189.     register pset last, p;
  190.  
  191.     /*
  192.      *  A represents th 'input' values for which the outputs assume
  193.      *  the integer value 'value
  194.      */
  195.     if (list == NIL(symbolic_list_t)) {
  196.     /*
  197.      *  Simulate these inputs against the on-set; then, insert into the
  198.      *  new on-set a 1 in the proper position
  199.      */
  200.     S = cv_intersect(A, PLA->F);
  201.     foreach_set(S, last, p) {
  202.         set_insert(p, base + value);
  203.     }
  204.     *newF = sf_append(*newF, S);
  205.  
  206.     /*
  207.      *  'simulate' these inputs against the don't-care set
  208.     S = cv_intersect(A, PLA->D);
  209.     *newD = sf_append(*newD, S);
  210.      */
  211.  
  212.     } else {
  213.     /* intersect and recur with the OFF-set */
  214.     S = cof_output(PLA->R, cube.first_part[cube.output] + list->pos);
  215.     if (A != NIL(set_family_t)) {
  216.         S1 = cv_intersect(A, S);
  217.         free_cover(S);
  218.         S = S1;
  219.     }
  220.     find_inputs(S, PLA, list->next, base, value*2, newF, newD);
  221.     free_cover(S);
  222.  
  223.     /* intersect and recur with the ON-set */
  224.     S = cof_output(PLA->F, cube.first_part[cube.output] + list->pos);
  225.     if (A != NIL(set_family_t)) {
  226.         S1 = cv_intersect(A, S);
  227.         free_cover(S);
  228.         S = S1;
  229.     }
  230.     find_inputs(S, PLA, list->next, base, value*2 + 1, newF, newD);
  231.     free_cover(S);
  232.     }
  233. }
  234.  
  235.  
  236. #if 0
  237. find_dc_inputs(PLA, list, base, maxval, newF, newD)
  238. pPLA PLA;
  239. symbolic_list_t *list;
  240. int base, maxval;
  241. pcover *newF, *newD;
  242. {
  243.     pcover A, S, S1;
  244.     symbolic_list_t *p2;
  245.     register pset p, last;
  246.     register int i;
  247.  
  248.     /* painfully find the points for which the symbolic output is dc */
  249.     A = NIL(set_family_t);
  250.     for(p2=list; p2!=NIL(symbolic_list_t); p2=p2->next) {
  251.     S = cof_output(PLA->D, cube.first_part[cube.output] + p2->pos);
  252.     if (A == NIL(set_family_t)) {
  253.         A = S;
  254.     } else {
  255.         S1 = cv_intersect(A, S);
  256.         free_cover(S);
  257.         free_cover(A);
  258.         A = S1;
  259.     }
  260.     }
  261.  
  262.     S = cv_intersect(A, PLA->F);
  263.     *newF = sf_append(*newF, S);
  264.  
  265.     S = cv_intersect(A, PLA->D);
  266.     foreach_set(S, last, p) {
  267.     for(i = base; i < base + maxval; i++) {
  268.         set_insert(p, i);
  269.     }
  270.     }
  271.     *newD = sf_append(*newD, S);
  272.     free_cover(A);
  273. }
  274. #endif
  275.  
  276. map_symbolic(PLA)
  277. pPLA PLA;
  278. {
  279.     symbolic_t *p1;
  280.     symbolic_list_t *p2;
  281.     int var, base, num_vars, num_binary_vars, *new_part_size;
  282.     int new_size, size_added, num_deleted_vars, num_added_vars, newvar;
  283.     pset compress;
  284.  
  285.     /* Verify legal values are in the symbolic lists */
  286.     for(p1 = PLA->symbolic; p1 != NIL(symbolic_t); p1 = p1->next) {
  287.     for(p2=p1->symbolic_list; p2!=NIL(symbolic_list_t); p2=p2->next) {
  288.         if (p2->variable  < 0 || p2->variable >= cube.num_binary_vars) {
  289.         fatal(".symbolic requires binary variables");
  290.         }
  291.     }
  292.     }
  293.  
  294.     /*
  295.      *  size_added = width added for all symbolic variables
  296.      *  num_deleted_vars = # binary variables to be deleted
  297.      *  num_added_vars = # new mv variables
  298.      *  compress = a cube which will be used to compress the set families
  299.      */
  300.     size_added = 0;
  301.     num_added_vars = 0;
  302.     for(p1 = PLA->symbolic; p1 != NIL(symbolic_t); p1 = p1->next) {
  303.     size_added += 1 << p1->symbolic_list_length;
  304.     num_added_vars++;
  305.     }
  306.     compress = set_full(PLA->F->sf_size + size_added);
  307.     for(p1 = PLA->symbolic; p1 != NIL(symbolic_t); p1 = p1->next) {
  308.     for(p2=p1->symbolic_list; p2!=NIL(symbolic_list_t); p2=p2->next) {
  309.         set_remove(compress, p2->variable*2);
  310.         set_remove(compress, p2->variable*2+1);
  311.     }
  312.     }
  313.     num_deleted_vars = ((PLA->F->sf_size + size_added) - set_ord(compress))/2;
  314.  
  315.     /* compute the new cube constants */
  316.     num_vars = cube.num_vars - num_deleted_vars + num_added_vars;
  317.     num_binary_vars = cube.num_binary_vars - num_deleted_vars;
  318.     new_size = cube.size - num_deleted_vars*2 + size_added;
  319.     new_part_size = ALLOC(int, num_vars);
  320.     new_part_size[num_vars-1] = cube.part_size[cube.num_vars-1];
  321.     for(var = cube.num_binary_vars; var < cube.num_vars-1; var++) {
  322.     new_part_size[var-num_deleted_vars] = cube.part_size[var];
  323.     }
  324.  
  325.     /* re-size the covers, opening room for the new mv variables */
  326.     base = cube.first_part[cube.output];
  327.     PLA->F = sf_addcol(PLA->F, base, size_added);
  328.     PLA->D = sf_addcol(PLA->D, base, size_added);
  329.     PLA->R = sf_addcol(PLA->R, base, size_added);
  330.  
  331.     /* compute the values for the new mv variables */
  332.     newvar = (cube.num_vars - 1) - num_deleted_vars;
  333.     for(p1 = PLA->symbolic; p1 != NIL(symbolic_t); p1 = p1->next) {
  334.     PLA->F = map_symbolic_cover(PLA->F, p1->symbolic_list, base);
  335.     PLA->D = map_symbolic_cover(PLA->D, p1->symbolic_list, base);
  336.     PLA->R = map_symbolic_cover(PLA->R, p1->symbolic_list, base);
  337.     base += 1 << p1->symbolic_list_length;
  338.     new_part_size[newvar++] = 1 << p1->symbolic_list_length;
  339.     }
  340.  
  341.     /* delete the binary variables which disappear */
  342.     PLA->F = sf_compress(PLA->F, compress);
  343.     PLA->D = sf_compress(PLA->D, compress);
  344.     PLA->R = sf_compress(PLA->R, compress);
  345.  
  346.     symbolic_hack_labels(PLA, PLA->symbolic, compress,
  347.         new_size, cube.size, size_added);
  348.     setdown_cube();
  349.     FREE(cube.part_size);
  350.     cube.num_vars = num_vars;
  351.     cube.num_binary_vars = num_binary_vars;
  352.     cube.part_size = new_part_size;
  353.     cube_setup();
  354.     set_free(compress);
  355. }
  356.  
  357.  
  358. pcover map_symbolic_cover(T, list, base)
  359. pcover T;
  360. symbolic_list_t *list;
  361. int base;
  362. {
  363.     pset last, p;
  364.     foreach_set(T, last, p) {
  365.     form_bitvector(p, base, 0, list);
  366.     }
  367.     return T;
  368. }
  369.  
  370.  
  371. form_bitvector(p, base, value, list)
  372. pset p;            /* old cube, looking at binary variables */
  373. int base;        /* where in mv cube the new variable starts */
  374. int value;        /* current value for this recursion */
  375. symbolic_list_t *list;    /* current place in the symbolic list */
  376. {
  377.     if (list == NIL(symbolic_list_t)) {
  378.     set_insert(p, base + value);
  379.     } else {
  380.     switch(GETINPUT(p, list->variable)) {
  381.         case ZERO:
  382.         form_bitvector(p, base, value*2, list->next);
  383.         break;
  384.         case ONE:
  385.         form_bitvector(p, base, value*2+1, list->next);
  386.         break;
  387.         case TWO:
  388.         form_bitvector(p, base, value*2, list->next);
  389.         form_bitvector(p, base, value*2+1, list->next);
  390.         break;
  391.         default:
  392.         fatal("bad cube in form_bitvector");
  393.     }
  394.     }
  395. }
  396.  
  397.  
  398. symbolic_hack_labels(PLA, list, compress, new_size, old_size, size_added)
  399. pPLA PLA;
  400. symbolic_t *list;
  401. pset compress;
  402. int new_size, old_size, size_added;
  403. {
  404.     int i, base;
  405.     char **oldlabel;
  406.     symbolic_t *p1;
  407.     symbolic_label_t *p3;
  408.  
  409.     /* hack with the labels */
  410.     if ((oldlabel = PLA->label) == NIL(char *))
  411.     return;
  412.     PLA->label = ALLOC(char *, new_size);
  413.     for(i = 0; i < new_size; i++) {
  414.     PLA->label[i] = NIL(char);
  415.     }
  416.  
  417.     /* copy the binary variable labels and unchanged mv variable labels */
  418.     base = 0;
  419.     for(i = 0; i < cube.first_part[cube.output]; i++) {
  420.     if (is_in_set(compress, i)) {
  421.         PLA->label[base++] = oldlabel[i];
  422.     } else {
  423.         if (oldlabel[i] != NIL(char)) {
  424.         FREE(oldlabel[i]);
  425.         }
  426.     }
  427.     }
  428.  
  429.     /* add the user-defined labels for the symbolic outputs */
  430.     for(p1 = list; p1 != NIL(symbolic_t); p1 = p1->next) {
  431.     p3 = p1->symbolic_label;
  432.     for(i = 0; i < (1 << p1->symbolic_list_length); i++) {
  433.         if (p3 == NIL(symbolic_label_t)) {
  434.         PLA->label[base+i] = ALLOC(char, 10);
  435.         (void) sprintf(PLA->label[base+i], "X%d", i);
  436.         } else {
  437.         PLA->label[base+i] = p3->label;
  438.         p3 = p3->next;
  439.         }
  440.     }
  441.     base += 1 << p1->symbolic_list_length;
  442.     }
  443.  
  444.     /* copy the labels for the binary outputs which remain */
  445.     for(i = cube.first_part[cube.output]; i < old_size; i++) {
  446.     if (is_in_set(compress, i + size_added)) {
  447.         PLA->label[base++] = oldlabel[i];
  448.     } else {
  449.         if (oldlabel[i] != NIL(char)) {
  450.         FREE(oldlabel[i]);
  451.         }
  452.     }
  453.     }
  454.     FREE(oldlabel);
  455. }
  456.  
  457. static pcover fsm_simplify(F)
  458. pcover F;
  459. {
  460.     pcover D, R;
  461.     D = new_cover(0);
  462.     R = complement(cube1list(F));
  463.     F = espresso(F, D, R);
  464.     free_cover(D);
  465.     free_cover(R);
  466.     return F;
  467. }
  468.  
  469.  
  470. void disassemble_fsm(pPLA PLA, int verbose_mode)
  471. {
  472.     int nin, nstates, nout;
  473.     int before, after, present_state, next_state, i, j;
  474.     pcube next_state_mask, present_state_mask, state_mask, p, p1, last;
  475.     pcover go_nowhere, F, tF;
  476.  
  477.     /* We make the DISGUSTING assumption that the first 'n' outputs have
  478.      *  been created by .symbolic-output, and represent a one-hot encoding
  479.      * of the next state.  'n' is the size of the second-to-last multiple-
  480.      * valued variable (i.e., before the outputs
  481.      */
  482.  
  483.     if (cube.num_vars - cube.num_binary_vars != 2) {
  484.     fprintf(stderr,
  485.     "use .symbolic and .symbolic-output to specify\n");
  486.     fprintf(stderr,
  487.     "the present state and next state field information\n");
  488.     fatal("disassemble_pla: need two multiple-valued variables\n");
  489.     }
  490.  
  491.     nin = cube.num_binary_vars;
  492.     nstates = cube.part_size[cube.num_binary_vars];
  493.     nout = cube.part_size[cube.num_vars - 1];
  494.     if (nout < nstates) {
  495.     fprintf(stderr,
  496.         "use .symbolic and .symbolic-output to specify\n");
  497.     fprintf(stderr,
  498.         "the present state and next state field information\n");
  499.     fatal("disassemble_pla: # outputs < # states\n");
  500.     }
  501.  
  502.  
  503.     present_state = cube.first_part[cube.num_binary_vars];
  504.     present_state_mask = new_cube();
  505.     for(i = 0; i < nstates; i++) {
  506.     set_insert(present_state_mask, i + present_state);
  507.     }
  508.  
  509.     next_state = cube.first_part[cube.num_binary_vars+1];
  510.     next_state_mask = new_cube();
  511.     for(i = 0; i < nstates; i++) {
  512.     set_insert(next_state_mask, i + next_state);
  513.     }
  514.  
  515.     state_mask = set_or(new_cube(), next_state_mask, present_state_mask);
  516.  
  517.     F = new_cover(10);
  518.  
  519.  
  520.     /*
  521.      *  check for arcs which go from ANY state to state #i
  522.      */
  523.     for(i = 0; i < nstates; i++) {
  524.     tF = new_cover(10);
  525.     foreach_set(PLA->F, last, p) {
  526.         if (setp_implies(present_state_mask, p)) { /* from any state ! */
  527.         if (is_in_set(p, next_state + i)) {
  528.             tF = sf_addset(tF, p);
  529.         }
  530.         }
  531.     }
  532.     before = tF->count;
  533.     if (before > 0) {
  534.         tF = fsm_simplify(tF);
  535.         /* don't allow the next state to disappear ... */
  536.         foreach_set(tF, last, p) {
  537.         set_insert(p, next_state + i);
  538.         }
  539.         after = tF->count;
  540.         F = sf_append(F, tF);
  541.         if (verbose_mode) {
  542.         printf("# state EVERY to %d, before=%d after=%d\n",
  543.             i, before, after);
  544.         }
  545.     }
  546.     }
  547.  
  548.  
  549.     /*
  550.      *  some 'arcs' may NOT have a next state -- handle these
  551.      *  we must unravel the present state part
  552.      */
  553.     go_nowhere = new_cover(10);
  554.     foreach_set(PLA->F, last, p) {
  555.     if (setp_disjoint(p, next_state_mask)) { /* no next state !! */
  556.         go_nowhere = sf_addset(go_nowhere, p);
  557.     }
  558.     }
  559.     before = go_nowhere->count;
  560.     go_nowhere = unravel_range(go_nowhere,
  561.                 cube.num_binary_vars, cube.num_binary_vars);
  562.     after = go_nowhere->count;
  563.     F = sf_append(F, go_nowhere);
  564.     if (verbose_mode) {
  565.     printf("# state ANY to NOWHERE, before=%d after=%d\n", before, after);
  566.     }
  567.  
  568.  
  569.     /*
  570.      *  minimize cover for all arcs from state #i to state #j
  571.      */
  572.     for(i = 0; i < nstates; i++) {
  573.     for(j = 0; j < nstates; j++) {
  574.         tF = new_cover(10);
  575.         foreach_set(PLA->F, last, p) {
  576.         /* not EVERY state */
  577.         if (! setp_implies(present_state_mask, p)) {
  578.             if (is_in_set(p, present_state + i)) {
  579.             if (is_in_set(p, next_state + j)) {
  580.                 p1 = set_save(p);
  581.                 set_diff(p1, p1, state_mask);
  582.                 set_insert(p1, present_state + i);
  583.                 set_insert(p1, next_state + j);
  584.                 tF = sf_addset(tF, p1);
  585.                 set_free(p1);
  586.             }
  587.             }
  588.         }
  589.         }
  590.         before = tF->count;
  591.         if (before > 0) {
  592.         tF = fsm_simplify(tF);
  593.         /* don't allow the next state to disappear ... */
  594.         foreach_set(tF, last, p) {
  595.             set_insert(p, next_state + j);
  596.         }
  597.         after = tF->count;
  598.         F = sf_append(F, tF);
  599.         if (verbose_mode) {
  600.             printf("# state %d to %d, before=%d after=%d\n",
  601.                 i, j, before, after);
  602.         }
  603.         }
  604.     }
  605.     }
  606.  
  607.  
  608.     free_cube(state_mask);
  609.     free_cube(present_state_mask);
  610.     free_cube(next_state_mask);
  611.  
  612.     free_cover(PLA->F);
  613.     PLA->F = F;
  614.     free_cover(PLA->D);
  615.     PLA->D = new_cover(0);
  616.  
  617.     setdown_cube();
  618.     FREE(cube.part_size);
  619.     cube.num_binary_vars = nin;
  620.     cube.num_vars = nin + 3;
  621.     cube.part_size = ALLOC(int, cube.num_vars);
  622.     cube.part_size[cube.num_binary_vars] = nstates;
  623.     cube.part_size[cube.num_binary_vars+1] = nstates;
  624.     cube.part_size[cube.num_binary_vars+2] = nout - nstates;
  625.     cube_setup();
  626.  
  627.     foreach_set(PLA->F, last, p) {
  628.     kiss_print_cube(stdout, PLA, p, "~1");
  629.     }
  630. }
  631.